package org.haifi.game.util;

import java.net.InetSocketAddress;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.mina.core.session.IoSession;

import com.google.common.collect.Maps;

/**
 * 统一存放当前玩家的所有ioSession，用来统计当前在线人员
 * 
 * userSessions与playerSessions可能只需要保留一个
 * 
 * 
 * @author joycube2
 * 
 */
public class SessionUtils {
	private static ThreadLocal<IoSession> currentSesion = new ThreadLocal<IoSession>();
	/**
	 * 当前所有的ioSession
	 * 
	 * key:ioSession.id
	 * 
	 * value:ioSession
	 */
	private static Map<Long, IoSession> sessions = Maps.newConcurrentMap();
	/**
	 * 帐号与ioSession
	 * 
	 * key:帐号id
	 * 
	 * value:ioSession
	 */
	private static Map<Integer, IoSession> userSessions = Maps
			.newConcurrentMap();
	/**
	 * 角色与ioSession
	 * 
	 * key:角色id
	 * 
	 * value:ioSession
	 */
	private static Map<Integer, IoSession> playerSessions = Maps
			.newConcurrentMap();

	public static final String USER_ID = "user_id";
	public static final String PLAYER_ID = "player_id";
	public static final String USER = "USER";
	public static final String PLAYER = "PLAYER";

	/**
	 * 添加一个新的session,如果当前未设置USER_ID,PLAYER_ID,则只添加至sessions集合中
	 * 
	 * @param ioSession
	 */
	public static void addNewIoSession(IoSession ioSession) {
		if (log.isInfoEnabled()) {
			log.info("add new ioSession with id:" + ioSession.getId());
		}
		sessions.put(ioSession.getId(), ioSession);
		Integer userId = (Integer) ioSession.getAttribute(USER_ID);
		if (userId != null) {
			if (log.isInfoEnabled()) {
				log.info("add new user session with userId:" + userId);
			}
			userSessions.put(userId, ioSession);
		}
		Integer playerId = (Integer) ioSession.getAttribute(PLAYER_ID);
		if (playerId != null) {
			if (log.isInfoEnabled()) {
				log.info("add new player session with playerId:" + playerId);
			}
			userSessions.put(playerId, ioSession);
		}
	}

	/**
	 * 将新session添加至userSessions，提供给玩家新注册帐号使用
	 * 
	 * @param ioSession
	 */
	public static void addNewUserIoSession(IoSession ioSession) {
		Integer userId = (Integer) ioSession.getAttribute(USER_ID);
		if (userId != null) {
			if (log.isInfoEnabled()) {
				log.info("add new user session with userId:" + userId);
			}
			userSessions.put(userId, ioSession);
		} else {
			log.error("add new user session failed with userId:" + userId);
		}
	}

	public static void addNewPlayerIoSession(IoSession ioSession) {
		Integer playerId = (Integer) ioSession.getAttribute(PLAYER_ID);
		if (playerId != null) {
			if (log.isInfoEnabled()) {
				log.info("add new player session with playerId:" + playerId);
			}
			playerSessions.put(playerId, ioSession);
		} else {
			log
					.error("add new player session failed with playerId:"
							+ playerId);
		}
	}

	/**
	 * 移除ioSession
	 * 
	 * 同时从三个session集合中移除
	 * 
	 * @param ioSession
	 * 
	 */
	public static void removeIoSession(IoSession ioSession) {
		if (log.isInfoEnabled()) {
			log.info("remove ioSession with id:" + ioSession.getId());
		}
		sessions.remove(ioSession.getId());
		Integer userId = (Integer) ioSession.getAttribute(USER_ID);
		if (userId != null) {
			log.info("remove user session with userId:" + userId);
			userSessions.remove(userId);
		}
		Integer playerId = (Integer) ioSession.getAttribute(PLAYER_ID);
		if (playerId != null) {
			log.info("remove player session with playerId:" + playerId);
			playerSessions.remove(playerId);
		}
	}

	/**
	 * 设置当前线程的sessionId
	 * 
	 * @param sessionId
	 */
	public static void setCurrentSession(IoSession session) {
		currentSesion.set(session);
	}

	/**
	 * 获得当前的ioSession
	 * 
	 * @return
	 */
	public static IoSession getCurrentSession() {
		return currentSesion.get();
	}

	/**
	 * 玩家当前在线
	 * 
	 * @param userId
	 * @return
	 */
	public static boolean isOnline(Integer userId) {
		return userSessions.containsKey(userId);
	}

	/**
	 * 获得当前玩家的ip
	 * @return
	 */
	public static String getCurrentIp() {
		IoSession ioSession = getCurrentSession();
		return ((InetSocketAddress) ioSession.getRemoteAddress()).getHostName();
	}

	private static final Log log = LogFactory.getLog(SessionUtils.class);
}
